cmake_minimum_required(VERSION 3.10)

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

project(
    XenEngine
    LANGUAGES CXX C
    VERSION 0.0.1
    DESCRIPTION "a toy engin based on vulkan"
    )

############################
# decide whether use ccache to compile
############################

option(ENABLE_CCACHE "use ccache to compile" ON)

if (${ENABLE_CCACHE}) 
    find_program(CCACHE_FOUND ccache)
    set(CMAKE_C_COMPILER   ${CCACHE_PROGRAM})
    set(CMAKE_CXX_COMPILER ${CCACHE_PROGRAM})
endif()

############################
# find external libraries
############################

find_package(OpenGL REQUIRED)
find_package(SDL2 REQUIRED)

# use pkg-config to find ode, glew
find_package(PkgConfig REQUIRED)
pkg_check_modules(ode REQUIRED IMPORTED_TARGET ode)
pkg_check_modules(glew REQUIRED IMPORTED_TARGET glew)

add_subdirectory(external)

############################
# build libXenEngine.a
############################

set(VERSION_MAJOR ${CMAKE_PROJECT_VERSION_MAJOR})
set(VERSION_MINOR ${CMAKE_PROJECT_VERSION_MINOR})
set(VERSION_PATCH ${CMAKE_PROJECT_VERSION_PATCH})
set(PROJECT_PATH "${PROJECT_SOURCE_DIR}")
configure_file("${PROJECT_PATH}/include/xen/config/config.hpp.in"
                "${PROJECT_PATH}/include/xen/config/config.hpp"
                @ONLY)

aux_source_directory(src/xen SRC)
aux_source_directory(src/xen/event SRC)
aux_source_directory(src/xen/renderer SRC)
aux_source_directory(src/xen/imgui SRC)
aux_source_directory(src/xen/audio SRC)
aux_source_directory(src/xen/physical SRC)
aux_source_directory(src/platform/opengl SRC)

aux_source_directory(external/imgui IMGUI_SRC)
list(APPEND IMGUI_SRC external/imgui/backends/imgui_impl_sdl.cpp external/imgui/backends/imgui_impl_opengl3.cpp)

add_library(${PROJECT_NAME} STATIC)

target_sources(
    ${PROJECT_NAME}
    PRIVATE ${SRC} ${IMGUI_SRC}
    )

################## decide which audio library to use #####################
option(ENABLE_SDL2_MIXER "use SDL2_mixer to play audio" ON)
option(ENABLE_OpenAL "use openal to play audio(can't work on MacOSX)" ON)

if (ENABLE_SDL2_MIXER)
    message(STATUS "Enable SDL2 Mixer")

    pkg_check_modules(sdl2_mixer REQUIRED IMPORTED_TARGET sdl2_mixer)

    target_include_directories(
        ${PROJECT_NAME}
        PUBLIC ${sdl2_mixer_INCLUDE_DIRS}
        )
    target_link_libraries(
        ${PROJECT_NAME}
        PUBLIC ${sdl2_mixer_LIBRARIES}
        )
    target_link_directories(
        ${PROJECT_NAME}
        PUBLIC ${sdl2_mixer_LIBDIR}
        )
    target_compile_definitions(
        ${PROJECT_NAME}
        PUBLIC ENABLE_SDL2_MIXER
        )

    aux_source_directory(src/platform/sdl_mixer SDL2_MIXER_SRC)
    target_sources(
        ${PROJECT_NAME}
        PRIVATE ${SDL2_MIXER_SRC}
        )
endif()

if(ENABLE_OpenAL)
    message(STATUS "Enable OpenAL")

    # On My MacOS, OpenAL was deprecated, so I use openal-soft to instead(but can't work also :-( ).
    # If you want to use OpenAL, please uncomment this line below, and comment below 3 lines
    # find_package(OpenAL REQUIRED)
    set(OPENAL_INCLUDE_DIRS /usr/local/Cellar/openal-soft/1.21.0/include/)
    set(OPENAL_LIBDIR /usr/local/Cellar/openal-soft/1.21.0/lib/)
    set(OPENAL_LIBRARIES openal)

    target_include_directories(
        ${PROJECT_NAME}
        PUBLIC ${OPENAL_INCLUDE_DIRS}
        )
    target_link_libraries(
        ${PROJECT_NAME}
        PUBLIC ${OPENAL_LIBRARIES}
        )
    target_link_directories(
        ${PROJECT_NAME}
        PUBLIC ${OPENAL_LIBDIR}
        )
    target_compile_definitions(
        ${PROJECT_NAME}
        PUBLIC ENABLE_OPENAL
        )

    aux_source_directory(src/platform/openal OPENAL_SRC)
    target_sources(
        ${PROJECT_NAME}
        PRIVATE ${OPENAL_SRC}
        )
endif()

if (NOT ENABLE_SDL2_MIXER AND NOT ENABLE_OpenAL)
    message(FATAL_ERROR "please choose one audio library")
endif()
#############################################################


##decide whether Assimp verify model's data while loading model###
option(ASSIMP_VERIFY_MODEL_DATA "let assimp verify model's data while loading model" OFF)
if (ASSIMP_VERIFY_MODEL_DATA)
    target_compile_definitions(
        ${PROJECT_NAME}
        PUBLIC ENABLE_ASSIMP_VALIDATION
        )
endif()
#############################################################

target_link_libraries(
    ${PROJECT_NAME}
    PUBLIC ${OPENGL_LIBRARIES} ${ode_LIBRARIES} ${glew_LIBRARIES} spdlog glm assimp SDL2::SDL2
    )

target_link_directories(
    ${PROJECT_NAME}
    PUBLIC ${ode_LIBDIR} ${glew_LIBDIR} ${sdl2_mixer_LIBDIR}
)

target_include_directories(
    ${PROJECT_NAME}
    PUBLIC include ${OPENGL_INCLUDE_DIRS} ${ode_INCLUDE_DIRS} ${sdl2_mixer_INCLUDE_DIRS} ${glew_INCLUDE_DIRS} external external/imgui
    )

target_compile_features(
    ${PROJECT_NAME}
    PUBLIC cxx_std_17
    )

if (${CMAKE_BUILD_TYPE} MATCHES Debug)
    target_compile_definitions(
        ${PROJECT_NAME}
        PUBLIC XEN_ENABLE_ASSERT
    )
endif()

############################
# build sandbox
############################

option(XENENGINE_BUILD_SANDBOX "build example" ON)

if (XENENGINE_BUILD_SANDBOX)
    add_subdirectory(sandbox)
endif()
